/**
 * @file igh_master.c
 * @brief IgH EtherCAT主站实现
 * 
 * 该文件实现了基于IgH EtherCAT主站的接口
 */

#include "ethercat_interface.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* 包含IgH EtherCAT主站头文件 */
#include "../igh/ecrt.h"

/* 定义IgH主站相关数据结构 */
typedef struct {
    EtherCATInterface interface;  /* 必须放在第一位，用于类型转换 */
    
    /* IgH特有数据 */
    ec_master_t *master;
    ec_master_state_t master_state;
    ec_domain_t *domain;
    ec_domain_state_t domain_state;
    uint8_t *domain_pd;
    int slave_count;
} IGHMaster;

/* IgH接口实现函数 */
static bool igh_init(const char *ifname) {
    IGHMaster *igh = (IGHMaster *)((EtherCATInterface *)__func__ - offsetof(IGHMaster, interface.init));
    
    /* 请求主站实例 */
    igh->master = ecrt_request_master(0);
    if (!igh->master) {
        fprintf(stderr, "Failed to request master instance\n");
        return false;
    }
    
    /* 创建域 */
    igh->domain = ecrt_master_create_domain(igh->master);
    if (!igh->domain) {
        fprintf(stderr, "Failed to create domain\n");
        return false;
    }
    
    return true;
}

static int igh_config_init(void) {
    IGHMaster *igh = (IGHMaster *)((EtherCATInterface *)__func__ - offsetof(IGHMaster, interface.config_init));
    
    /* IgH主站需要手动配置从站，这里简化处理 */
    ec_master_state_t ms;
    ecrt_master_state(igh->master, &ms);
    igh->slave_count = ms.slaves_responding;
    
    return igh->slave_count;
}

static bool igh_config_map(void *io_map) {
    IGHMaster *igh = (IGHMaster *)((EtherCATInterface *)__func__ - offsetof(IGHMaster, interface.config_map));
    
    /* 激活主站 */
    if (ecrt_master_activate(igh->master)) {
        fprintf(stderr, "Failed to activate master\n");
        return false;
    }
    
    /* 获取过程数据 */
    if (!(igh->domain_pd = ecrt_domain_data(igh->domain))) {
        fprintf(stderr, "Failed to get process data\n");
        return false;
    }
    
    return true;
}

static bool igh_config_dc(void) {
    /* 在IgH中，分布式时钟配置通常是针对特定从站的 */
    /* 这里简化实现 */
    return true;
}

static bool igh_state_check(uint16_t slave, EtherCATState state, int timeout) {
    IGHMaster *igh = (IGHMaster *)((EtherCATInterface *)__func__ - offsetof(IGHMaster, interface.state_check));
    
    /* 转换状态枚举 */
    ec_state_t ec_state;
    switch (state) {
        case EC_STATE_INIT: ec_state = EC_STATE_INIT; break;
        case EC_STATE_PREOP: ec_state = EC_STATE_PRE_OP; break;
        case EC_STATE_SAFEOP: ec_state = EC_STATE_SAFE_OP; break;
        case EC_STATE_OPERATIONAL: ec_state = EC_STATE_OPERATIONAL; break;
        default: return false;
    }
    
    /* 检查状态 */
    return ecrt_master_state_check(igh->master, slave, ec_state, &timeout) == 1;
}

static bool igh_write_state(uint16_t slave, EtherCATState state) {
    IGHMaster *igh = (IGHMaster *)((EtherCATInterface *)__func__ - offsetof(IGHMaster, interface.write_state));
    
    /* 转换状态枚举 */
    ec_state_t ec_state;
    switch (state) {
        case EC_STATE_INIT: ec_state = EC_STATE_INIT; break;
        case EC_STATE_PREOP: ec_state = EC_STATE_PRE_OP; break;
        case EC_STATE_SAFEOP: ec_state = EC_STATE_SAFE_OP; break;
        case EC_STATE_OPERATIONAL: ec_state = EC_STATE_OPERATIONAL; break;
        default: return false;
    }
    
    /* 设置状态 */
    return ecrt_master_state_change(igh->master, slave, ec_state, 0) == 0;
}

static bool igh_send_processdata(void) {
    IGHMaster *igh = (IGHMaster *)((EtherCATInterface *)__func__ - offsetof(IGHMaster, interface.send_processdata));
    
    ecrt_domain_queue(igh->domain);
    ecrt_master_send(igh->master);
    return true;
}

static int igh_receive_processdata(int timeout) {
    IGHMaster *igh = (IGHMaster *)((EtherCATInterface *)__func__ - offsetof(IGHMaster, interface.receive_processdata));
    
    ecrt_master_receive(igh->master);
    ecrt_domain_process(igh->domain);
    
    /* 获取工作计数器 */
    ec_domain_state_t ds;
    ecrt_domain_state(igh->domain, &ds);
    return ds.working_counter;
}

static bool igh_read_state(void) {
    IGHMaster *igh = (IGHMaster *)((EtherCATInterface *)__func__ - offsetof(IGHMaster, interface.read_state));
    
    ecrt_master_state(igh->master, &igh->master_state);
    return true;
}

static void igh_close(void) {
    IGHMaster *igh = (IGHMaster *)((EtherCATInterface *)__func__ - offsetof(IGHMaster, interface.close));
    
    /* 释放主站资源 */
    if (igh->master) {
        ecrt_release_master(igh->master);
        igh->master = NULL;
    }
}

static int igh_get_slave_count(void) {
    IGHMaster *igh = (IGHMaster *)((EtherCATInterface *)__func__ - offsetof(IGHMaster, interface.get_slave_count));
    return igh->slave_count;
}

static uint8_t* igh_get_slave_inputs(uint16_t slave) {
    /* 在IgH中，通常通过PDO条目访问从站数据 */
    /* 这里简化实现，返回NULL */
    return NULL;
}

static uint8_t* igh_get_slave_outputs(uint16_t slave) {
    /* 在IgH中，通常通过PDO条目访问从站数据 */
    /* 这里简化实现，返回NULL */
    return NULL;
}

/* 创建IgH主站实例 */
EtherCATInterface* create_igh_master(void) {
    IGHMaster *igh = (IGHMaster *)malloc(sizeof(IGHMaster));
    if (!igh) {
        return NULL;
    }
    
    memset(igh, 0, sizeof(IGHMaster));
    
    /* 初始化接口函数 */
    igh->interface.init = igh_init;
    igh->interface.config_init = igh_config_init;
    igh->interface.config_map = igh_config_map;
    igh->interface.config_dc = igh_config_dc;
    igh->interface.state_check = igh_state_check;
    igh->interface.write_state = igh_write_state;
    igh->interface.send_processdata = igh_send_processdata;
    igh->interface.receive_processdata = igh_receive_processdata;
    igh->interface.read_state = igh_read_state;
    igh->interface.close = igh_close;
    igh->interface.get_slave_count = igh_get_slave_count;
    igh->interface.get_slave_inputs = igh_get_slave_inputs;
    igh->interface.get_slave_outputs = igh_get_slave_outputs;
    
    return &igh->interface;
}

/* 销毁IgH主站实例 */
void destroy_igh_master(EtherCATInterface *interface) {
    if (interface) {
        IGHMaster *igh = (IGHMaster *)interface;
        igh->interface.close();
        free(igh);
    }
}